from docx import Document
import re


def validate_sentence_endings_by_paragraph(chinese_text, english_text):
    # 只关注句子结束符号：句号、问号、感叹号
    ending_punctuation_map = {
        '。': '.',
        '？': '?',
        '！': '!',
    }

    # 中文引号集合（包括全角和半角）
    chinese_quotes = {'"', "'", "“", "”", "‘", "’", "「", "」", "『", "』"}

    # 常见缩写列表（避免误判为句子结束）
    abbreviations = {
        'no', 'mr', 'mrs', 'ms', 'dr', 'prof', 'st', 'ave', 'blvd', 'co',
        'inc', 'ltd', 'etc', 'e.g', 'i.e', 'vs', 'p.s', 'a.m', 'p.m',
        'vol', 'fig', 'eq', 'ch', 'sec', 'ref', 'ex', 'al', 'ed', 'est'
    }

    # 按段落分割文档
    chinese_paragraphs = [p.strip() for p in chinese_text.split('\n') if p.strip()]
    english_paragraphs = [p.strip() for p in english_text.split('\n') if p.strip()]

    # 检查段落数量是否匹配
    if len(chinese_paragraphs) != len(english_paragraphs):
        return False, f"段落数量不匹配: 中文 {len(chinese_paragraphs)} 段, 英文 {len(english_paragraphs)} 段"

    all_valid = True
    report = []

    # 逐段校验
    for para_idx, (ch_para, en_para) in enumerate(zip(chinese_paragraphs, english_paragraphs)):
        # 提取中文段落结束符号序列和对应句子
        ch_endings = []
        ch_sentences = []
        current_sentence = ""
        # 打印调试
        print(f"中文段落 {para_idx + 1}: {ch_para}")
        print(f"英文段落 {para_idx + 1}: {en_para}")

        for char in ch_para:
            current_sentence += char
            if char in ending_punctuation_map:
                ch_endings.append(ending_punctuation_map[char])
                ch_sentences.append(current_sentence.strip())
                current_sentence = ""

        # 添加最后未结束的句子
        if current_sentence:
            ch_sentences.append(current_sentence.strip())

        # 提取英文段落结束符号序列和对应句子（更智能的分句）
        en_endings = []
        en_sentences = []
        current_sentence = ""
        en_errors = []  # 记录英文中的中文结束符号

        # 使用更智能的分句逻辑，避免缩写中的句点被误判
        words = re.split(r'(\s+)', en_para)  # 保留空格
        for i, word in enumerate(words):
            current_sentence += word

            # 检查单词是否包含内容
            stripped_word = word.strip()
            if not stripped_word:
                continue

            # 检查是否以结束符+引号结尾（包括英文和中文引号）
            if len(stripped_word) >= 2 and stripped_word[-1] in chinese_quotes and stripped_word[
                -2] in ending_punctuation_map.values():
                # 处理结束符+引号的情况
                ending_char = stripped_word[-2]
                clean_word = re.sub(r'[^\w]', '', stripped_word[:-2]).lower()
                is_abbreviation = clean_word in abbreviations

                # 获取下一个非空字符
                next_char = None
                j = i + 1
                while j < len(words) and next_char is None:
                    next_word = words[j].strip()
                    if next_word:
                        # 跳过开头的引号（包括中文引号）
                        start_idx = 0
                        while start_idx < len(next_word) and next_word[start_idx] in chinese_quotes:
                            start_idx += 1
                        if start_idx < len(next_word):
                            next_char = next_word[start_idx]
                    j += 1

                # 判断是否结束句子
                if (not is_abbreviation and
                        (next_char is None or
                         not next_char.isalpha() or
                         not next_char.islower())):
                    en_endings.append(ending_char)
                    en_sentences.append(current_sentence.strip())
                    current_sentence = ""

            # 检查常规结束符（没有引号）
            elif stripped_word[-1] in ending_punctuation_map.values():
                # 检查是否是缩写
                clean_word = re.sub(r'[^\w]', '', stripped_word).lower()
                is_abbreviation = clean_word in abbreviations

                # 获取下一个非空字符
                next_char = None
                j = i + 1
                while j < len(words) and next_char is None:
                    next_word = words[j].strip()
                    if next_word:
                        # 跳过开头的引号（包括中文引号）
                        start_idx = 0
                        while start_idx < len(next_word) and next_word[start_idx] in chinese_quotes:
                            start_idx += 1
                        if start_idx < len(next_word):
                            next_char = next_word[start_idx]
                    j += 1

                # 判断是否结束句子
                if (not is_abbreviation and
                        (next_char is None or
                         not next_char.isalpha() or
                         not next_char.islower())):
                    en_endings.append(stripped_word[-1])
                    en_sentences.append(current_sentence.strip())
                    current_sentence = ""

            # 检查中文结束符号错误
            for char in word:
                if char in ending_punctuation_map:
                    # 计算当前位置
                    pos = sum(len(w) for w in words[:i]) + len(word[:word.index(char) + 1])
                    error_msg = f"位置 {pos}: 中文结束符 '{char}' (应为 '{ending_punctuation_map[char]}')"
                    en_errors.append(error_msg)

        # 添加最后未结束的句子
        if current_sentence:
            en_sentences.append(current_sentence.strip())

        # 打印调试信息
        print(f"中文句子数: {len(ch_sentences)}, 英文句子数: {len(en_sentences)}")
        print(f"中文结束符: {ch_endings}")
        print(f"英文结束符: {en_endings}")

        # 检查本段结束符号是否匹配
        para_valid = True
        diff = []

        # 检查结束符号数量
        if len(ch_endings) != len(en_endings):
            para_valid = False
            diff.append(f"  结束符号数量不匹配: 中文 {len(ch_endings)} 个, 英文 {len(en_endings)} 个")

            # 显示句子数量差异
            min_sentences = min(len(ch_sentences), len(en_sentences))
            if len(ch_sentences) > min_sentences:
                diff.append(f"  中文多出句子:")
                for i in range(min_sentences, len(ch_sentences)):
                    diff.append(f"    - {ch_sentences[i]}")
            elif len(en_sentences) > min_sentences:
                diff.append(f"  英文多出句子:")
                for i in range(min_sentences, len(en_sentences)):
                    diff.append(f"    - {en_sentences[i]}")

        # 逐位置比较结束符号
        min_len = min(len(ch_endings), len(en_endings))
        for i in range(min_len):
            if ch_endings[i] != en_endings[i]:
                para_valid = False
                diff.append(f"  位置 {i + 1}: 中文结束符 '{ch_endings[i]}' ≠ 英文结束符 '{en_endings[i]}'")

                # 显示对应的句子
                ch_sentence = ch_sentences[i] if i < len(ch_sentences) else "（无对应句子）"
                en_sentence = en_sentences[i] if i < len(en_sentences) else "（无对应句子）"
                diff.append(f"    中文句子: {ch_sentence}")
                diff.append(f"    英文句子: {en_sentence}")

        # 处理多余结束符号
        if len(ch_endings) > min_len:
            para_valid = False
            extra = ch_endings[min_len:]
            diff.append(f"  中文多出 {len(extra)} 个结束符号: {extra}")
            # 显示多余句子
            for i in range(min_len, len(ch_sentences)):
                if i < len(ch_sentences):
                    diff.append(f"    多余中文句子: {ch_sentences[i]}")
        if len(en_endings) > min_len:
            para_valid = False
            extra = en_endings[min_len:]
            diff.append(f"  英文多出 {len(extra)} 个结束符号: {extra}")
            # 显示多余句子
            for i in range(min_len, len(en_sentences)):
                if i < len(en_sentences):
                    diff.append(f"    多余英文句子: {en_sentences[i]}")

        # 添加英文中的中文结束符号错误
        if en_errors:
            para_valid = False
            diff.append("  英文段落中的中文结束符号错误:")
            for error in en_errors:
                # 尝试找到错误位置对应的句子
                match = re.search(r'位置 (\d+)', error)
                if match:
                    pos = int(match.group(1))
                    found = False
                    for idx, sent in enumerate(en_sentences):
                        if pos <= len(sent):
                            diff.append(f"    {error} - 所在句子: {sent}")
                            found = True
                            break
                        pos -= len(sent) + 1  # +1 for the space between sentences
                    if not found:
                        diff.append(f"    {error}")
                else:
                    diff.append(f"    {error}")

        # 汇总本段结果
        if not para_valid:
            all_valid = False
            report.append(f"段落 {para_idx + 1} 校验失败:")
            report.extend(diff)
        else:
            report.append(f"段落 {para_idx + 1} 校验通过")

    # 返回整体结果
    if all_valid:
        return True, "所有段落结束符号完全对应"
    else:
        return False, "\n".join(report)


def read_word_document(file_path):
    """读取Word文档内容并返回段落文本"""
    doc = Document(file_path)
    paragraphs = [p.text for p in doc.paragraphs if p.text.strip()]
    return "\n".join(paragraphs)


def validate_word_documents(chinese_doc_path, english_doc_path):
    """校验中英文Word文档的句子结束符号"""
    # 读取Word文档内容
    try:
        chinese_text = read_word_document(chinese_doc_path)
        english_text = read_word_document(english_doc_path)
    except Exception as e:
        return False, f"读取文档失败: {str(e)}"

    # 执行校验
    return validate_sentence_endings_by_paragraph(chinese_text, english_text)


# ===== 使用示例 =====
if __name__ == "__main__":
    # Word文档路径（替换为实际路径）
    chinese_doc_path = "./simplifyAI test.zh-CN.docx"  # 中文Word文档路径
    english_doc_path = "./simplifyAI test.docx"  # 英文Word文档路径

    # 执行校验
    is_valid, message = validate_word_documents(chinese_doc_path, english_doc_path)

    # 输出结果
    print("=" * 50)
    print("整体校验结果:", "通过" if is_valid else "失败")
    print("=" * 50)
    print("详细报告:")
    print(message)

    # 将报告保存到文件
    report_file = "punctuation_validation_report.txt"
    with open(report_file, "w", encoding="utf-8") as f:
        f.write(message)
    print(f"\n报告已保存至: {report_file}")